package com.iraeta.service.oa.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.iraeta.dao.bpm.HrYgdamDao;
import com.iraeta.dao.main.basic.OadanganrenyuanDao;
import com.iraeta.dao.main.work.TblogDao;
import com.iraeta.dao.oa.EnumItemDao;
import com.iraeta.dao.oa.RenYuanDangAnDao;
import com.iraeta.entity.bpm.HrYgdam;
import com.iraeta.entity.main.Oadanganrenyuan;
import com.iraeta.entity.main.Tblog;
import com.iraeta.entity.main.TbworkId;
import com.iraeta.entity.main.vo.OADangAnRenYuanResult;
import com.iraeta.entity.oa.EnumItem;
import com.iraeta.entity.oa.EnumItemType;
import com.iraeta.service.oa.RenYuanDangAnService;
import com.iraeta.uitl.Util;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

@Service
public class RenYuanDangAnServiceImpl implements RenYuanDangAnService {
    @Resource
    RenYuanDangAnDao renYuanDangAnDao;      //oa数据库的数据源
    @Resource
    EnumItemDao enumItemDao;                //oa数据库的数据源

    @Resource
    OadanganrenyuanDao oadanganrenyuanDao;  //本系统的数据源
    @Resource
    TblogDao tblogDao;                      //本系统的数据源

    @Resource
    HrYgdamDao hrYgdamDao;                  //bpm系统的数据源

    @Override
    public void processTongBu() {
        OADangAnRenYuanResult oaDangAnRenYuanResult = new OADangAnRenYuanResult();
        List<Map<String, Object>> downloadData = this.getAllRenYuanDangAnFromOA();
        for (Map<String, Object> downloadDataMap : downloadData) {
            String renYuanId = Util.parseStringFromMap(downloadDataMap, "field0001");
            try {
                String name = Util.parseStringFromMap(downloadDataMap, "field0002");
                String idCard = Util.parseStringFromMap(downloadDataMap, "field0003");
                String phone = Util.parseStringFromMap(downloadDataMap, "field0021");
                String renYuanDangAnStatusStr = Util.parseStringFromMap(downloadDataMap, "renYuanDangAnStatusStr");
                if(renYuanDangAnStatusStr == null){
                    throw new RuntimeException("在职状态异常");
                }

                String jsonData = JSON.toJSONString(downloadDataMap);
                Oadanganrenyuan oadanganrenyuanForDb = oadanganrenyuanDao.selectByRenYuanId(idCard);
                if(oadanganrenyuanForDb == null){
                    oadanganrenyuanForDb = new Oadanganrenyuan(renYuanId, name, idCard, phone, renYuanDangAnStatusStr);
                    oadanganrenyuanForDb.setJsondata(jsonData);
                    oadanganrenyuanForDb.setLastupdatetime(new Date());
                    oadanganrenyuanDao.insert(oadanganrenyuanForDb);
                    oaDangAnRenYuanResult.insertList.add(oadanganrenyuanForDb);
                }else{
                    if(!oadanganrenyuanForDb.getJsondata().equals(jsonData)){   //如果数据库有数据， 并且下载的内容和数据库的内容发生的变更
                        if((oadanganrenyuanForDb.getStatusname().equals("在职") || oadanganrenyuanForDb.getStatusname().equals("试用"))
                                && (renYuanDangAnStatusStr.equals("离职") || renYuanDangAnStatusStr.equals("退休")) ){           //如果是删除人员档案  现在是在职试用，以后是离职退休
                            oadanganrenyuanForDb.setJsondata(jsonData);
                            oadanganrenyuanForDb.setStatusname(renYuanDangAnStatusStr);
                            oadanganrenyuanForDb.setLastupdatetime(new Date());
                            oadanganrenyuanDao.updateByPrimaryKey(oadanganrenyuanForDb);
                            oaDangAnRenYuanResult.deleteList.add(oadanganrenyuanForDb);
                        }else{          //如果是修改人员档案
                            oadanganrenyuanForDb.setRenyuanid(renYuanId);
                            oadanganrenyuanForDb.setName(name);
                            oadanganrenyuanForDb.setPhone(phone);
                            oadanganrenyuanForDb.setStatusname(renYuanDangAnStatusStr);
                            oadanganrenyuanForDb.setJsondata(jsonData);
                            oadanganrenyuanForDb.setLastupdatetime(new Date());
                            oadanganrenyuanDao.updateByPrimaryKey(oadanganrenyuanForDb);
                            oaDangAnRenYuanResult.updateList.add(oadanganrenyuanForDb);
                        }

                    }
                }
            }catch (Exception e){
                oaDangAnRenYuanResult.exceptionList.add(renYuanId);
            }
        }
        this.updateBpmData(oaDangAnRenYuanResult);

        String exceptionDesc = oaDangAnRenYuanResult.exceptionList.size() > 0 ? String.join(",", oaDangAnRenYuanResult.exceptionList) : "";
        Tblog tblog = new Tblog();
        tblog.setLogtime(new Date());
        tblog.setWorkid(TbworkId.oaRenYuanDangAnToBpm);
        tblog.setUptatecount(oaDangAnRenYuanResult.getInsertCount() + oaDangAnRenYuanResult.getUpdateCount() + oaDangAnRenYuanResult.getDeleteCount());
        tblog.setNeirong("插入档案数" + oaDangAnRenYuanResult.getInsertCount() + "条,修改档案数"+oaDangAnRenYuanResult.getUpdateCount()
                +"条,删除档案数" + oaDangAnRenYuanResult.getDeleteCount() + "条,异常档案数" + oaDangAnRenYuanResult.getExceptionCount() + "条,异常数据[" + exceptionDesc + "]");
        tblogDao.insert(tblog);
    }

    private void updateBpmData(OADangAnRenYuanResult oaDangAnRenYuanResult){
        oaDangAnRenYuanResult.setExceptionCount(oaDangAnRenYuanResult.exceptionList.size());
        for (Oadanganrenyuan oadanganrenyuan : oaDangAnRenYuanResult.deleteList) {
            oaDangAnRenYuanResult.addDeleteCount();
            HrYgdam hrYgdam = hrYgdamDao.selectByIdCard(oadanganrenyuan.getIdcard());
            if(hrYgdam == null) continue;
            hrYgdam.setCryzt("离职");
            hrYgdamDao.updateByPrimaryKey(hrYgdam);
        }
        oaDangAnRenYuanResult.setInsertCount(oaDangAnRenYuanResult.insertList.size());
        oaDangAnRenYuanResult.setUpdateCount(oaDangAnRenYuanResult.updateList.size());

        List<Oadanganrenyuan> oadanganrenyuanList = new ArrayList<>();
        oadanganrenyuanList.addAll(oaDangAnRenYuanResult.insertList);
        oadanganrenyuanList.addAll(oaDangAnRenYuanResult.updateList);
        List<EnumItem> sexEnumItem = enumItemDao.listByREF_ENUMID(EnumItemType.sex);        //OA性别枚举
        List<EnumItem> minZuEnumItem = enumItemDao.listByREF_ENUMID(EnumItemType.minZu);    //OA民族枚举
        List<EnumItem> hunYinEnumItem = enumItemDao.listByREF_ENUMID(EnumItemType.hunYin);        //OA婚姻枚举
        List<EnumItem> mianMaoEnumItem = enumItemDao.listByREF_ENUMID(EnumItemType.mianMao);        //OA面貌枚举
        List<EnumItem> xueLiEnumItem = enumItemDao.listByREF_ENUMID(EnumItemType.xueLi);        //OA学历枚举
        List<EnumItem> yuanGongLieXinEnumItem = enumItemDao.listByREF_ENUMID(EnumItemType.yuanGongLieXin);        //OA员工类型枚举

        for (Oadanganrenyuan oadanganrenyuan : oadanganrenyuanList) {
            boolean isAdd = false;
            HrYgdam hrYgdam = hrYgdamDao.selectByIdCard(oadanganrenyuan.getIdcard());
            if(hrYgdam == null){
                isAdd = true;
                long maxIID = hrYgdamDao.selectMaxIID();
                hrYgdam = new HrYgdam();
                hrYgdam.setIid(maxIID);
                hrYgdam.setCcode(String.valueOf(maxIID));
                hrYgdam.setCgzdw("伊莱特能源装备股份有限公司");
                hrYgdam.setCryzt("在职");
                hrYgdam.setCmaker("管理员");
                hrYgdam.setCmakerno("admin");
                hrYgdam.setCrybh(Util.getBusinessNoV2());       //人员编号  格式20231125XXXXX  5位的随机数
                hrYgdam.setCsfzh(oadanganrenyuan.getIdcard());  //身份证
            }
            //基本信息
            JSONObject oaDangYuanJb = JSON.parseObject(oadanganrenyuan.getJsondata());
            hrYgdam.setCxm(oadanganrenyuan.getName());                      //姓名
            //员工类型
            hrYgdam.setCyglx(yuanGongLieXinEnumItem.stream().filter(x->String.valueOf(x.getId()).equals(oaDangYuanJb.getString("field0166"))).findFirst().orElseGet(()->new EnumItem(-1, "科室职员")).getTitle());
            hrYgdam.setCzgzw("");//主岗职务
            hrYgdam.setCgzbm(""); //供职部门 todo 完成
            hrYgdam.setCgzbmbm("");   //供职部门编码

            //人员信息
            hrYgdam.setCyddh(oadanganrenyuan.getPhone());                   //电话
            hrYgdam.setCcph(oaDangYuanJb.getString("field0193"));       //车牌号
            //性别 民族 婚姻 面貌 学历 枚举设置
            hrYgdam.setCxb(sexEnumItem.stream().filter(x->String.valueOf(x.getId()).equals(oaDangYuanJb.getString("field0005"))).findFirst().orElseGet(()->new EnumItem(-1, "男")).getTitle());
            hrYgdam.setCmz(minZuEnumItem.stream().filter(x->String.valueOf(x.getId()).equals(oaDangYuanJb.getString("field0008"))).findFirst().orElseGet(()->new EnumItem(-1, "汉族")).getTitle());
            hrYgdam.setChyzk(hunYinEnumItem.stream().filter(x->String.valueOf(x.getId()).equals(oaDangYuanJb.getString("field0010"))).findFirst().orElseGet(()->new EnumItem(-1, "未婚")).getTitle());
            hrYgdam.setCzzmm(mianMaoEnumItem.stream().filter(x->String.valueOf(x.getId()).equals(oaDangYuanJb.getString("field0011"))).findFirst().orElseGet(()->new EnumItem(-1, "群众")).getTitle());
            hrYgdam.setCzgxl(xueLiEnumItem.stream().filter(x->String.valueOf(x.getId()).equals(oaDangYuanJb.getString("field0029"))).findFirst().orElseGet(()->new EnumItem(-1, "未知")).getTitle());

            //入职办理
            if(!isAdd) hrYgdam.setCryzt(oadanganrenyuan.getStatusname());   //人员状态
            hrYgdam.setDrzrq(new Date());                                   //入职日期
            hrYgdam.setCsfzs("否");                                         //是否住宿
            hrYgdam.setCfkbl("否");                                         //是否饭卡
            hrYgdam.setCdwgl(new BigDecimal(1));                       //单位工龄  需要计算
            hrYgdam.setDsyqqs(new Date());                                  //试用期开始
            hrYgdam.setDsyqjs(new Date());                                  //试用期结束
            hrYgdam.setChkb(false);                                         //上交资料户口本
            hrYgdam.setCzczs(false);                                         //上交资料职称证书
            hrYgdam.setCaqjy(false);                                        //上交资料安全教育
            hrYgdam.setCtjzl(true);                                         //上交体检
            hrYgdam.setCsb(true);                                           //上交社保
            hrYgdam.setCsjzlsfz(true);                                       //上交身份证
            hrYgdam.setCsb(true);                                           //上交社保
            hrYgdam.setCxlz(true);                                           //上交学历证

            //入职准备
            hrYgdam.setCrysx("合同工");                                                         //人员属性
            hrYgdam.setDzzsq(DateUtil.parseDate("2023-10-01"));                      //转正日期

            //社保公积金信息
            hrYgdam.setCgjjzh("");              //公积金账户
            hrYgdam.setCjnsfcg("");             //原单位是否缴纳五险一金       //是否
            hrYgdam.setCsbzt("");             //原单位缴纳五险一金状态   如 五险 五险一金等
            hrYgdam.setCsbszd("");              //元单位社保所在地
            hrYgdam.setCbjsbyy("");             //不交社保原因
            hrYgdam.setCbdwsbjncg("");          //本单位是否缴纳社保
            hrYgdam.setCbdwsbzt("");            //本单位缴纳状态

            if(isAdd){
                hrYgdamDao.insertSelective(hrYgdam);
            }else{
                hrYgdamDao.updateByPrimaryKey(hrYgdam);
            }
        }
    }

    private List<Map<String, Object>> getAllRenYuanDangAnFromOA() {
        List<EnumItem> renYuanDangAnStatusEnumItem = enumItemDao.listByREF_ENUMID(EnumItemType.RenYuanDangAnStatus);
        List<Long> normalStatus = renYuanDangAnStatusEnumItem.stream().filter(x->x.getTitle().equals("在职") || x.getTitle().equals("试用") || x.getTitle().equals("离职") || x.getTitle().equals("退休"))
                .map(EnumItem::getId).collect(Collectors.toList());
        List<Map<String,Object >> dangAnList = renYuanDangAnDao.listAllRenYuanDangAn();
        List<Map<String,Object >> jiaoYuList = renYuanDangAnDao.listAllRenYuanDangAnJiaoYu();      //教育经历
        List<Map<String,Object >> gongZuoList = renYuanDangAnDao.listAllRenYuanDangAnGongZuo();     //工作单位
        List<Map<String,Object >> familyList = renYuanDangAnDao.listAllRenYuanDangAnFamily();      //家庭成员
//        List<Map<String,Object >> renZhiList = renYuanDangAnDao.listAllRenYuanDangAnRenZhi();      //任职经历
//        List<Map<String,Object >> heTongList = renYuanDangAnDao.listAllRenYuanDangAnHeTong();      //合同记录
//        List<Map<String,Object >> ZZZSList = renYuanDangAnDao.listAllRenYuanDangAnZZZS();        //职称证书

        final List<Map<String,Object >> res = new CopyOnWriteArrayList<>();  //保存结果
        ExecutorService service = Executors.newFixedThreadPool(5);
        CountDownLatch countDownLatch = new CountDownLatch(dangAnList.size());


        for (Map<String, Object> dangAnMap : dangAnList) {
            service.execute(new Runnable(){
                @Override
                public void run() {
                    try {
                        final long id = Util.parseLongFromMap(dangAnMap, "ID");
                        final long renYuanDangAnStatus = Util.parseLongFromMap(dangAnMap, "field0004");
                        final String renYuanDangAnStatusStr = renYuanDangAnStatusEnumItem.stream().filter(x-> x.getId() == renYuanDangAnStatus).findFirst().get().getTitle();
                        if(normalStatus.contains(renYuanDangAnStatus)){
                            List<Map<String,Object >> dangAnJiaoYu = jiaoYuList.stream().filter(x->Util.parseLongFromMap(x, "formmain_id") == id).collect(Collectors.toList());
                            List<Map<String,Object >> dangAnGongZuo = gongZuoList.stream().filter(x->Util.parseLongFromMap(x, "formmain_id") == id).collect(Collectors.toList());
                            List<Map<String,Object >> dangAnFamily = familyList.stream().filter(x->Util.parseLongFromMap(x, "formmain_id") == id).collect(Collectors.toList());
//                            List<Map<String,Object >> dangAnRenZhi = renZhiList.stream().filter(x->Util.parseLongFromMap(x, "formmain_id") == id).collect(Collectors.toList());
//                            List<Map<String,Object >> dangAnHeTong = heTongList.stream().filter(x->Util.parseLongFromMap(x, "formmain_id") == id).collect(Collectors.toList());
//                            List<Map<String,Object >> dangAnZZZS = ZZZSList.stream().filter(x->Util.parseLongFromMap(x, "formmain_id") == id).collect(Collectors.toList());
                            dangAnMap.put("jiaoYu", dangAnJiaoYu);
                            dangAnMap.put("gongZuo", dangAnGongZuo);
                            dangAnMap.put("family", dangAnFamily);
//                            dangAnMap.put("renZhi", dangAnRenZhi);
//                            dangAnMap.put("heTong", dangAnHeTong);
//                            dangAnMap.put("zzzs", dangAnZZZS);
                            dangAnMap.put("renYuanDangAnStatusStr", renYuanDangAnStatusStr);
                            res.add(dangAnMap);
                        }
                    }catch (Exception e){
                        e.printStackTrace();
                    }finally {
                        countDownLatch.countDown();
                    }
                }
            });
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        service.shutdown();
        return res;
    }
}
